import {app, BrowserWindow, ipcMain, shell} from 'electron'
import {createRequire} from 'node:module'
import {fileURLToPath} from 'node:url'
import path from 'node:path'
import os from 'node:os'
import {update} from './update'

const require = createRequire(import.meta.url)
const __dirname = path.dirname(fileURLToPath(import.meta.url))

// 已构建的目录结构
//
// ├─┬ dist-electron
// │ ├─┬ main
// │ │ └── index.js    > Electron 主目录
// │ └─┬ preload
// │   └── index.mjs   > 预加载脚本
// ├─┬ dist
// │ └── index.html    > Electron 渲染目录
//

// 设置环境变量，APP_ROOT 指向项目根目录
process.env.APP_ROOT = path.join(__dirname, '../..')
// electron编译后目录
export const MAIN_DIST = path.join(process.env.APP_ROOT, 'dist-electron')
// react编译后目录
export const RENDERER_DIST = path.join(process.env.APP_ROOT, 'dist')
// 开发模式下，electron 主进程的 URL
export const VITE_DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL
// 开发模式下 public 文件夹指向 ./public 目录，打包后指向 ./dist/public 目录
process.env.VITE_PUBLIC = VITE_DEV_SERVER_URL ? path.join(process.env.APP_ROOT, 'public') : RENDERER_DIST

// 禁用Windows 7的GPU加速
if (os.release().startsWith('6.1')) {
    app.disableHardwareAcceleration()
}

// 为Windows 10+通知设置应用程序名称
if (process.platform === 'win32') {
    app.setAppUserModelId(app.getName())
}

if (!app.requestSingleInstanceLock()) {
    app.quit()
    process.exit(0)
}

let win: BrowserWindow | null = null
// 预加载脚本路径
const preload = path.join(__dirname, '../preload/index.mjs')
// 渲染进程的 HTML 文件路径
const indexHtml = path.join(RENDERER_DIST, 'index.html')

/**
 * 创建一个新的浏览器窗口。
 *
 * @returns 返回一个Promise，表示创建窗口的操作是否成功。
 */
async function createWindow() {
    win = new BrowserWindow({
        title: 'Main window',
        icon: path.join(process.env.VITE_PUBLIC, 'favicon.ico'),
        webPreferences: {
            preload,
            // Warning: Enable nodeIntegration and disable contextIsolation is not secure in production
            // nodeIntegration: true,

            // Consider using contextBridge.exposeInMainWorld
            // Read more on https://www.electronjs.org/docs/latest/tutorial/context-isolation
            // contextIsolation: false,
        },
    })

    // 通过是否存在VITE_DEV_SERVER_URL来判断是否处于开发模式
    if (VITE_DEV_SERVER_URL) { // #298
        await win.loadURL(VITE_DEV_SERVER_URL)
        // 如果应用程序未打包，默认打开devTool窗口
        win.webContents.openDevTools()
    } else {
        await win.loadFile(indexHtml)
    }

    // 监听的'did-finish-load'（页面渲染完成）事件，并向渲染进程发送'main-process-message'消息
    win.webContents.on('did-finish-load', () => {
        console.log('[did-finish-load]渲染进程加载完成!')
        win?.webContents.send('main-process-message', new Date().toLocaleString())
    })

    // 所有https链接使用浏览器打开，而不是在应用程序中打开它们
    win.webContents.setWindowOpenHandler(({url}) => {
        if (url.startsWith('https:')) shell.openExternal(url)
        return {action: 'deny'}
    })

    // 自动更新功能
    update(win)
}

app.whenReady().then(createWindow)

app.on('window-all-closed', () => {
    win = null
    if (process.platform !== 'darwin') app.quit()
})

app.on('second-instance', () => {
    if (win) {
        // Focus on the main window if the user tried to open another
        if (win.isMinimized()) win.restore()
        win.focus()
    }
})

app.on('activate', () => {
    const allWindows = BrowserWindow.getAllWindows()
    if (allWindows.length) {
        allWindows[0].focus()
    } else {
        createWindow()
    }
})

// New window example arg: new windows url
ipcMain.handle('open-win', (_, arg) => {
    const childWindow = new BrowserWindow({
        webPreferences: {
            preload,
            nodeIntegration: true,
            contextIsolation: false,
        },
    })

    if (VITE_DEV_SERVER_URL) {
        childWindow.loadURL(`${VITE_DEV_SERVER_URL}#${arg}`)
    } else {
        childWindow.loadFile(indexHtml, {hash: arg})
    }
})
